#include "wx/wxprec.h"

#include "wx/dc.h"

//-----------------------------------------------------------------------------
// wxDC
//-----------------------------------------------------------------------------

IMPLEMENT_ABSTRACT_CLASS( wxDC, wxDCBase )

wxDC::wxDC() {
  m_ok = FALSE;
  m_mm_to_pix_x = ( double )wxGetDisplaySize().GetWidth() /
                  ( double )wxGetDisplaySizeMM().GetWidth();
  m_mm_to_pix_y = ( double )wxGetDisplaySize().GetHeight() /
                  ( double )wxGetDisplaySizeMM().GetHeight();
  m_needComputeScaleX = FALSE; /* not used yet */
  m_needComputeScaleY = FALSE; /* not used yet */
  m_logicalFunction = wxCOPY;
  m_pen = *wxBLACK_PEN;
  m_font = *wxNORMAL_FONT;
  m_brush = *wxWHITE_BRUSH;
}

void wxDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) {
  m_clipping = TRUE;
  m_clipX1 = x;
  m_clipY1 = y;
  m_clipX2 = x + width;
  m_clipY2 = y + height;
}

// ---------------------------------------------------------------------------
// get DC capabilities
// ---------------------------------------------------------------------------

void wxDC::DoGetSizeMM( int* width, int* height ) const {
  int w = 0;
  int h = 0;
  GetSize( &w, &h );
  if( width ) {
    *width = int( double( w ) / ( m_userScaleX * m_mm_to_pix_x ) );
  }
  if( height ) {
    *height = int( double( h ) / ( m_userScaleY * m_mm_to_pix_y ) );
  }
}

wxSize wxDC::GetPPI() const {
  return wxSize( 0, 0 );
}

void wxDC::ComputeScaleAndOrigin() {
  m_scaleX = m_logicalScaleX * m_userScaleX;
  m_scaleY = m_logicalScaleY * m_userScaleY;
}

void wxDC::SetMapMode( int mode ) {
  switch( mode ) {
    case wxMM_TWIPS:
      SetLogicalScale( twips2mm * m_mm_to_pix_x, twips2mm * m_mm_to_pix_y );
      break;
    case wxMM_POINTS:
      SetLogicalScale( pt2mm * m_mm_to_pix_x, pt2mm * m_mm_to_pix_y );
      break;
    case wxMM_METRIC:
      SetLogicalScale( m_mm_to_pix_x, m_mm_to_pix_y );
      break;
    case wxMM_LOMETRIC:
      SetLogicalScale( m_mm_to_pix_x / 10.0, m_mm_to_pix_y / 10.0 );
      break;
    default:
    case wxMM_TEXT:
      SetLogicalScale( 1.0, 1.0 );
      break;
  }
  m_mappingMode = mode;
  /*  we don't do this mega optimisation
      if (mode != wxMM_TEXT) {
          m_needComputeScaleX = TRUE;
          m_needComputeScaleY = TRUE;
      }
  */
}

void wxDC::SetUserScale( double x, double y ) {
  // allow negative ? -> no
  m_userScaleX = x;
  m_userScaleY = y;
  ComputeScaleAndOrigin();
}

void wxDC::SetLogicalScale( double x, double y ) {
  // allow negative ?
  m_logicalScaleX = x;
  m_logicalScaleY = y;
  ComputeScaleAndOrigin();
}

void wxDC::SetLogicalOrigin( wxCoord x, wxCoord y ) {
  m_logicalOriginX = x * m_signX;   // is this still correct ?
  m_logicalOriginY = y * m_signY;
  ComputeScaleAndOrigin();
}

void wxDC::SetDeviceOrigin( wxCoord x, wxCoord y ) {
  // only wxPostScripDC has m_signX = -1, we override SetDeviceOrigin there
  m_deviceOriginX = x;
  m_deviceOriginY = y;
  ComputeScaleAndOrigin();
}

void wxDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp ) {
  // only wxPostScripDC has m_signX = -1, we override SetAxisOrientation there
  m_signX = ( xLeftRight ?  1 : -1 );
  m_signY = ( yBottomUp  ? -1 :  1 );
  ComputeScaleAndOrigin();
}
